package com.easy.modules.sysmgr.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.easy.common.dao.BaseDaoI;
import com.easy.common.dao.IBaseDao;
import com.easy.common.util.BeanUtils;
import com.easy.common.util.string.ClobUtil;
import com.easy.common.web.page.Msg;
import com.easy.modules.sysmgr.entity.CompanyEntity;
import com.easy.modules.sysmgr.entity.DeptEntity;
import com.easy.modules.sysmgr.service.DeptServiceI;
import com.easy.modules.sysmgr.web.form.DeptForm;

@Service
@Transactional
public class DeptServiceImpl implements DeptServiceI {
	
	@Autowired
	private IBaseDao<DeptEntity> basedaoDept;

	@Autowired
	private BaseDaoI<CompanyEntity> basedaoCompany;

	@Override
	public Msg save(DeptForm form) {
		
		try {
			DeptEntity entity = new DeptEntity();
			BeanUtils.copyNotNullProperties(form, entity, new String[]{"duty", "year_target", "work_plan", "remark"});
			entity.setCreated(new Date()) ;
			
			entity.setDuty(ClobUtil.getClob(form.getDuty())) ;
			entity.setYear_target(ClobUtil.getClob(form.getYear_target())) ;
			entity.setWork_plan(ClobUtil.getClob(form.getWork_plan())) ;
			entity.setRemark(ClobUtil.getClob(form.getRemark())) ;

			if (form.getCompany_id() != null && !"".equals(form.getCompany_id())) {
				entity.setCompany(this.basedaoCompany.get(CompanyEntity.class, form.getCompany_id()));
			} else {
				return new Msg(true, "创建部门失败，部门必须隶属于某单位！") ;
			}
			
			if (form.getPid() != null && !"".equals(form.getPid())) {
				entity.setDept(this.basedaoDept.load(DeptEntity.class, form.getPid()));
			} 
			
			this.basedaoDept.add(entity);
			
			return new Msg(true, "创建成功！") ;
		} catch (BeansException e) {
			return new Msg(false, "创建失败！") ;
		}
	}

	@Override
	public Msg delete(String id) {
		try {
			DeptEntity t = this.basedaoDept.load(DeptEntity.class, id);
			del(t);
			
			return new Msg(true, "删除成功！") ;
		} catch (BeansException e) {
			return new Msg(false, "删除失败！") ;
		}
	}
	
	private void del(DeptEntity entity) {
		if (entity.getDepts() != null && entity.getDepts().size() > 0) {
			for (DeptEntity r : entity.getDepts()) {
				del(r);
			}
		}
		this.basedaoDept.delete(DeptEntity.class, entity.getId());
	}

	@Override
	public Msg edit(DeptForm form) {
		
		try {
			DeptEntity entity = this.basedaoDept.load(DeptEntity.class, form.getId());
			
			if(entity != null) {
				BeanUtils.copyNotNullProperties(form, entity, new String[]{"duty", "year_target", "work_plan", "remark"});
				entity.setModifyDate(new Date()) ;
				
				entity.setDuty(ClobUtil.getClob(form.getDuty())) ;
				entity.setYear_target(ClobUtil.getClob(form.getYear_target())) ;
				entity.setWork_plan(ClobUtil.getClob(form.getWork_plan())) ;
				entity.setRemark(ClobUtil.getClob(form.getRemark())) ;
				
				if (form.getPid() != null && !form.getPid().equalsIgnoreCase("")) {
					
					if(form.getPid().equals(entity.getId())) {
						return new Msg(false, "无法自关联节点！") ;
					}
					
					DeptEntity pt = basedaoDept.load(DeptEntity.class, form.getPid());
					isChildren(entity, pt);
					entity.setDept(pt);
				} else {
					entity.setDept(null);
				}
			}
			
			return new Msg(true, "编辑成功！") ;
		} catch (BeansException e) {
			return new Msg(false, "编辑失败！") ;
		}
	}
	
	/**
	 * 判断是否是将当前节点修改到当前节点的子节点
	 * @param entity 当前节点
	 * @param pt 要修改到的节点
	 * @return
	 */
	private boolean isChildren(DeptEntity entity, DeptEntity pt) {
		if (pt != null && pt.getDept() != null) {
			if (pt.getDept().getId().equalsIgnoreCase(entity.getId())) {
				pt.setDept(null);
				return true;
			} else {
				return isChildren(entity, pt.getDept());
			}
		}
		return false;
	}
	

	@Override
	public DeptForm get(String id) {

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("id", id);
		DeptEntity entity = (DeptEntity) this.basedaoDept.queryObject("select t from DeptEntity t where t.id = :id", params);
		
		DeptForm form = new DeptForm();
		
		if(null != entity) {
			BeanUtils.copyNotNullProperties(entity, form, new String[]{"duty", "year_target", "work_plan", "remark"});
			if (entity.getDept() != null) {
				form.setPid(entity.getDept().getId());
			}
			form.setCompany_id(entity.getCompany().getId()) ;
		}
		
		form.setDuty(ClobUtil.getString(entity.getDuty())) ;
		form.setYear_target(ClobUtil.getString(entity.getYear_target())) ;
		form.setWork_plan(ClobUtil.getString(entity.getWork_plan())) ;
		form.setRemark(ClobUtil.getString(entity.getRemark())) ;
		
		return form ;
	}

	@Override
	public List<DeptForm> tree(DeptForm form) {
		String hql = "select t from DeptEntity t where t.company.id='"+form.getCompany_id()+"' and t.dept.id is null" ;
		
		List<DeptEntity> entitys = this.basedaoDept.list(hql) ;
		
		List<DeptForm> deptsform = new ArrayList<DeptForm>() ;
		
		for (DeptEntity DeptEntity : entitys) {
			deptsform.add(recursiveNode(DeptEntity)) ;
		}
		return deptsform ;
	}
	
	public DeptForm recursiveNode(DeptEntity entity) {
		DeptForm mf = new DeptForm() ;
		BeanUtils.copyNotNullProperties(entity, mf, new String[]{"duty", "year_target", "work_plan", "remark"}) ;
		
		mf.setDuty(ClobUtil.getString(entity.getDuty())) ;
		mf.setYear_target(ClobUtil.getString(entity.getYear_target())) ;
		mf.setWork_plan(ClobUtil.getString(entity.getWork_plan())) ;
		mf.setRemark(ClobUtil.getString(entity.getRemark())) ;
		
		mf.setText(entity.getName()) ;	
		
		if(null != entity.getDepts() && entity.getDepts().size() > 0) {
			mf.setState("closed") ;
			
			Set<DeptEntity> rs = entity.getDepts() ;
			List<DeptForm> children = new ArrayList<DeptForm>();
			for (DeptEntity de : rs) {
				
				DeptForm tn = recursiveNode(de) ;
				BeanUtils.copyNotNullProperties(de ,tn, new String[]{"duty", "year_target", "work_plan", "remark"}) ;
				tn.setDuty(ClobUtil.getString(entity.getDuty())) ;
				tn.setYear_target(ClobUtil.getString(de.getYear_target())) ;
				tn.setWork_plan(ClobUtil.getString(de.getWork_plan())) ;
				tn.setRemark(ClobUtil.getString(de.getRemark())) ;
				
				children.add(tn);
			}
			
			mf.setChildren(children) ;
			mf.setState("open");
		}
		return mf ;
	}

}
